extends Control

@onready var label:Label = $Label
@onready var bg = $ColorRect

@export var font:Font
@export var maxCharCountPerLine = 10
@export var chatCountPerSecond = 40
@export var padding = 2

var started = false
var timeLapse = 0
var msg:String
var currentChatCountInDisplay = 0
var bottomCenterPosition
var sceneCamera


func _ready():
	hide()
	

func startShow(_msg:String, _bottomCenterPosition = Vector2.ZERO):
	sceneCamera = get_tree().get_nodes_in_group("SceneCamera")[0]
	
	bottomCenterPosition = _bottomCenterPosition
	started = true
	timeLapse = 0
	msg = _msg
	currentChatCountInDisplay = 0


func showMsg(msg:String):
	var lines = []
	var currentLine = ""
	var text = ""
	
	var customFont = font
	var customFontSize = label.label_settings.font_size
	
	for char in msg:
		if customFont.get_string_size(currentLine + char, 0, -1, customFontSize).x <= maxCharCountPerLine * customFont.get_string_size("好", 0, -1, customFontSize).x:
			currentLine += char
		else:
			currentLine += "\n"
			lines.append(currentLine)
			currentLine = char + ""
	
	if currentLine != "": lines.append(currentLine)
	
	var maxLineX = 0
	for line in lines:
		var lineWidth = customFont.get_string_size(line, 0, -1, customFontSize).x
		if lineWidth > maxLineX:
			maxLineX = lineWidth
			
	var totalHeight = customFont.get_height(customFontSize) * lines.size() + (lines.size() - 1) * label.label_settings.line_spacing
	
	var msgSize = Vector2(maxLineX, totalHeight)
	var bgSize = msgSize + Vector2(padding * 2.0, padding * 2.0)
	var labelOffset = Vector2(padding, padding)
	
	for line in lines:
		text += line
		
	label.text = text
	label.size = msgSize
	label.position = labelOffset
	
	bg.size = bgSize
	
	var dialogTentativePosition = bottomCenterPosition - Vector2(bgSize.x / 2.0, bgSize.y)
	
	var borderMax = Vector2(dialogTentativePosition.x + bgSize.x, dialogTentativePosition.y + bgSize.y)
	var borderMaxView = Global.worldPos2ViewPos(borderMax, sceneCamera)
	var leftTopPosView = Global.worldPos2ViewPos(dialogTentativePosition, sceneCamera)
	
	if borderMaxView.x > Global.viewportWidth:
		var distance = abs(borderMaxView.x - Global.viewportWidth) 
		dialogTentativePosition.x -= distance
	elif leftTopPosView.x < 0:
		var distance = abs(leftTopPosView.x)
		dialogTentativePosition.x += distance
		
	position = dialogTentativePosition
	
	show()
	
	

func _physics_process(delta):
	if not started: return
	
	timeLapse += delta 
	var chatCount = floor(timeLapse * chatCountPerSecond) 
	if chatCount >= currentChatCountInDisplay:
		currentChatCountInDisplay = chatCount
		showMsg(msg.substr(0, chatCount))
	
	if currentChatCountInDisplay >= msg.length():
		started = false

